package utils;

import utils.math_utils.RandStream;

import components.Synapse;

/**
 * A class which applies random or constant values to a synapse, with the
 * intention of allowing the same random parameters to be applied to 
 * different synapse parameters for large groups of synapses with ease.
 * The prescribed usage of this class is that the default constructor be
 * invoked and random/constant values for each synapse parameter then be set
 * via provided mutators.
 * 
 * @author zach
 *
 */
public class SynapseRandomizer {
    
    /** Random Stream for U of UDF synaptic efficacy variables. */
    private RandStream u; 
    
    /** A constant value for U. */
    private double constU;
    
    /** Random Stream for D of UDF synaptic efficacy variables. */
    private RandStream d;
    
    /** A constant value for D. */
    private double constD;
    
    /** Random Stream for F of UDF synaptic efficacy variables. */
    private RandStream f;
    
    /** A constant value for F. */ 
    private double constF;
    
    /** Random Stream for the delay values of synapses. */
    private RandStream delay;
    
    /** A constant value for the delay. */
    private double constDelay;
    
    /** Random Stream for the decay values of synapses. */
    private RandStream decay;
    
    /** A constant value for the decay */
    private double constDecay;
    
    /** Random Stream for the weight values of synapses. */
    private RandStream w;
    
    /** A constant weight value. */
    private double constW;
    
    /**
     * Default Constructor.
     */
    public SynapseRandomizer () {
    }
    
    /**
     * Randomize (or set to constant) the various parameters of a synapse. 
     * CAUTION: If this method is used after some synapse values have already 
     * been set, those values will be overwritten.
     * @param syn the synapse to be randomized.
     */
    public void randomizeSynapse(Synapse syn) {

    	if (u != null) 
    		syn.setU(u.next());
    	else
    		syn.setU(constU);
    	
    	if (d != null) 
    		syn.setD(d.next());
    	else
    		syn.setD(constD);
    	
    	if (f != null) 
    		syn.setF(f.next());
    	else
    		syn.setF(constF);
    	
    	if (delay != null) 
    		syn.setDelay(delay.next());
    	else
    		syn.setDelay(constDelay);
    	
    	if(decay != null) 
    		syn.setDecay(decay.next());
    	 else
    		syn.setDecay(constDecay);
    	
    	if (w != null) 
    		syn.setW(w.next());
    	else
    		syn.setW(constW);

    }

    /****************************************************************
     *                     Getters and Setters                      *
     ****************************************************************/
    public void setU(RandStream u) {
        this.u = u;
    }
    
    public void setD(RandStream d) {
        this.d = d;
    }

    public void setF(RandStream f) {
        this.f = f;
    }
    
    public void setDelay(RandStream delay) {
        this.delay = delay;
    }
    
    public void setW(RandStream w) {
        this.w = w;
    }

	public double getConstU() {
		return constU;
	}

	public void setConstU(double constU) {
		this.constU = constU;
	}

	public double getConstD() {
		return constD;
	}

	public void setConstD(double constD) {
		this.constD = constD;
	}

	public double getConstF() {
		return constF;
	}

	public void setConstF(double constF) {
		this.constF = constF;
	}

	public double getConstDelay() {
		return constDelay;
	}

	public void setConstDelay(double constDelay) {
		this.constDelay = constDelay;
	}

	public double getConstW() {
		return constW;
	}

	public void setConstW(double constW) {
		this.constW = constW;
	}

	public RandStream getU() {
		return u;
	}

	public RandStream getD() {
		return d;
	}

	public RandStream getF() {
		return f;
	}

	public RandStream getDelay() {
		return delay;
	}

	public RandStream getW() {
		return w;
	}

	public RandStream getDecay() {
		return decay;
	}

	public void setDecay(RandStream decay) {
		this.decay = decay;
	}

	public double getConstDecay() {
		return constDecay;
	}

	public void setConstDecay(double constDecay) {
		this.constDecay = constDecay;
	}
		
}
